/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpSession;
import model.TipoUsuario;
import model.Usuario;

/**
 *
 * @author Carlos Francisco de Moura
 */
public class AuthorizationListener implements PhaseListener {

    @Override
    public void beforePhase(PhaseEvent event) {
        //adiquirindo o FacesContext.
        FacesContext context = event.getFacesContext();
        //adiquirindo a HttpSesson.
        HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
        //adquirindo a sessão (essa mesma onde você deverá guardar seu usuário no nível de sessão com descritor currentUser).
        String currentPage = context.getViewRoot().getViewId();
        //armazenando a página que fez a requisição. (a string da pág. atual ex: "/pag.jsf")
        Usuario user = (Usuario) session.getAttribute("currentUser");

        //bem, se não está logado redireciona pra lógica que (navigatio rule) atende a loginPage
        if (user == null) {

            // se já esta na pagina login, não redireciona, para evitar loop infinito
            if (!currentPage.equals(new String("/login.xhtml"))) {
                NavigationHandler nh = context.getApplication().getNavigationHandler();
                nh.handleNavigation(context, null, "loginPage");
            }

        } else {
            //verificar se o usuario atual tem acesso a página atual.
            if (!verificarAutorizacao(currentPage, user)) {
                //aqui a logica de não ter acesso... redicione novamente? faça algo... ??? 
                if (!currentPage.equals(new String("/restrito.xhtml"))) {
                    NavigationHandler nh = context.getApplication().getNavigationHandler();
                    nh.handleNavigation(context, null, "restrito");
                }
            }
            //caso contrário o jsf passa tranquilamente por aqui!!!
        }
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        //poderia ter sido escrito nesse evento depois da "fase" (lembra do básico do jsf, o ciclo de vida e as fases...
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    /** Verifica se o usuario estah autorizado a acessar a pagina requisitada */
    public boolean verificarAutorizacao(String paginaRequisitada, Usuario usuario) {

        boolean autorizado = false;
        String[] paginasAutorizadas = new String[]{"/home.xhtml", "/login.xhtml"};

        // se for usuario admin autoriza todas as paginas
        autorizado = usuario.getTipo().equals(TipoUsuario.ADMINISTRADOR);

        if (!autorizado) {
            // verifica se a pagina requisita encontra se na lista de paginas autorizadas
            for (String pagina : paginasAutorizadas) {
                if (paginaRequisitada.equals(pagina)) {
                    return true;
                }
            }
        }

        return autorizado;
    }
}